package com.jjh.back.interceptor;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import com.jjh.common.pojo.InfoEnum;
import com.jjh.common.servlet.BaseServlet;
import com.jjh.common.util.ConstatFinalUtil;
import com.jjh.users.pojo.AAdmins;
import com.jjh.users.pojo.AMenu;
import com.jjh.users.pojo.ARoleMenu;
import com.jjh.users.service.IAuthDbService;
import com.jjh.users.service.IUsersDbService;
import com.jjh.users.service.impl.AuthDbServiceImpl;
import com.jjh.users.service.impl.UsersDbServiceImpl;

@Component
public class AuthBackInceptor extends BaseServlet implements HandlerInterceptor
{
	@Autowired
	private IAuthDbService authDbService ;
	@Autowired
	private IUsersDbService usersDbService ;
	
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
	{
		System.out.println("==AuthFilter==preHandle");
		
		HttpSession session = request.getSession();
		/* 验证用户是否登陆,因为只登陆才放了adminsSess */
		AAdmins adminsSess = (AAdmins) session.getAttribute("adminsSess");
		if(adminsSess == null)
		{
			this.info = ConstatFinalUtil.INFO_JSON.getString(InfoEnum.INFO_LOGIN_ILLEGAL.getCode() + "") ; 
			session.setAttribute("info", info);
			/* 肯定木有登陆 */
			response.sendRedirect(request.getContextPath() + "/login");
			/* 一定return; */
			return false ; 
		}
		
		/* 判断单点登陆,根据上次登陆的ip判断
		 * session里面有一份信息
		 * 数据库里面也有一份信息
		 *  */
		/* 根据id查询数据库里面最新的信息 */
		Map<String,Object> condMap = new HashMap<String,Object>();
		condMap.clear();
		condMap.put("id", adminsSess.getId());
		AAdmins adminsDb = this.usersDbService.findOneAdminsService(condMap);
		if(!adminsDb.getLastLoginIp().equalsIgnoreCase(adminsSess.getLastLoginIp()))
		{
			/* 说明你的账号已经在其他地方登陆,强制下线 */
			this.info = ConstatFinalUtil.INFO_JSON.getString(InfoEnum.INFO_REMOTE_LOGIN.getCode() + "") ; 
			session.setAttribute("info", info);
			session.removeAttribute("lastLoginTime");
			session.removeAttribute("adminsSess");
			response.sendRedirect(request.getContextPath() + "/login");
			return false ; 
		}
		
		/* 验证权限 */
		boolean flag = verifyAuth(request,response,adminsDb);
		
		if(flag)
		{
			return true ;
		}else
		{
			/* 没有权限 */
			response.sendRedirect(request.getContextPath() + "/back/noAuth");
			return false ;
		}
	}
	

	/**
	 * 如何验证当前这个用户访问这个链接是否有权限呢
	 *  用户和角色有关系;用户和菜单没有关系  一个用户只能对应一个角色
	 *  查询出这个角色下面所有的菜单
	 *  如何知道当前页面访问的是哪个菜单呢
	 * @param request
	 * @param response
	 * @param adminsDb
	 * @return
	 */
	private boolean verifyAuth(HttpServletRequest request, HttpServletResponse response, AAdmins admins)
	{
		/* 留后门 */
 		if(admins.getId() == 1)
		{
			return true ;
		}
		
		/* 获取当前访问的url */
		String url =  request.getRequestURL() + "";
		String queryStr = request.getQueryString();
		if(queryStr != null)
		{
			url = url + "?" + queryStr ;
		}
		System.out.println("==url=="+ url);
		
		/* 查询当前管理员角色有哪些菜单 */
		Map<String,Object> condMap = new HashMap<String, Object>();
		
		condMap.clear();
		condMap.put("roleId", admins.getRoleId());
		List<ARoleMenu> roleMenuList = this.authDbService.findCondListRoleMenuService(null, condMap);
		for (ARoleMenu roleMenu : roleMenuList)
		{
			AMenu menuTemp = roleMenu.getMenu() ; 
			/* 因为menu里面有url;我们定义url的时候就是取自地址栏中的一部分 */
			if(url.indexOf(menuTemp.getUrl()) != -1)
			{
				/* 用户访问的url包含数据库中菜单的url;说明有权限 */
				return true ; 
			}
		}
		return false;
	}

}
